#include "mpx.h"
#include "com_hand.h"
#include "com_help.h"
#include "mpx_supt.h"
#include "com_dict.h"
#include "commands.h"
#include "err_hand.h"

/* Builds initial command dictionary and structures */
/* RETURNS: Error code on error, OK if okay */

int com_handler_init(void) 
{
	init_command_dict();
	
	/* Module R1 */
	add_command("date", "Shows and sets the date", HELP_DATE, *cmd_date);
	add_command("dir","Lists all executable MPX files", HELP_DIR, *cmd_dir);
	add_command("echo", "Prints arguments to the console", HELP_ECHO, *cmd_echo);
	add_command("help", "A simple help function", HELP_HELP, *cmd_help);
	add_command("quit", "Exits the MPX system", HELP_QUIT, *cmd_quit);
	add_command("version","Displays the MPX version number", HELP_VERSION, *cmd_version);

	/* Module R2 */
//	add_command("create","Creates a new process", HELP_CREATE, *cmd_create_pcb);
//	add_command("delete","Deletes a process", HELP_DELETE, *cmd_delete_pcb);
//	add_command("block","Places a process into a blocked queue", HELP_BLOCK, *cmd_block);
//	add_command("unblock","Places a process back into a ready queue", HELP_UNBLOCK, *cmd_unblock);
	add_command("suspend","Suspends a process", HELP_SUSPEND, *cmd_suspend);
	add_command("resume","Resumes a process from suspension", HELP_RESUME, *cmd_resume);
	add_command("priority","Changes a processes priority", HELP_PRIORITY, *cmd_priority);
	add_command("show","Shows detailed info on a process", HELP_SHOW, *cmd_show_pcb);
	add_command("showall","Lists all processes", HELP_SHOWALL, *cmd_show_all);
	add_command("showready","Lists all ready processes", HELP_SHOWREADY, *cmd_show_ready);
	add_command("showblocked","Lists all blocked processes", HELP_SHOWBLOCKED, *cmd_show_blocked);
	
	/* Module R3 */
//	add_command("run","Begins execution", HELP_DISPATCH, *cmd_dispatch);
//	add_command("loadr3","Module R3 sample processes", HELP_LOAD_PROCESSES, *cmd_load_processes);
	
	/* Module R4 */
	add_command("load","Loads an MPX process", HELP_LOAD, *cmd_load);
	add_command("kill","Terminates an MPX process", HELP_KILL, *cmd_kill);
	
	return OK;
}

/* Greets the user with the initial prompt */
void com_handler_welcome(void)
{
	int buff_len;
	
	buff_len = COM_USER_INPUT_LENGTH;
//	sys_req(CLEAR, TERMINAL, " ", &buff_len);
	printf("888b     d888 8888888b. Y88b   d88P  .d8888b.   .d8888b.   .d8888b.   .d8888b. \n");
	printf("8888b   d8888 888   Y88b Y88b d88P  d88P  Y88b d88P  Y88b d88P  Y88b d88P  Y88b\n");
	printf("88888b.d88888 888    888  Y88o88P          888 888    888 888    888 888    888\n");
	printf("888Y88888P888 888   d88P   Y888P         .d88P 888    888 888    888 888    888\n");
	printf("888 Y888P 888 8888888P\"    d888b     .od888P\"  888    888 888    888 888    888\n");
	printf("888  Y8P  888 888         d88888b   d88P\"      888    888 888    888 888    888\n");
	printf("888   \"   888 888        d88P Y88b  888\"       Y88b  d88P Y88b  d88P Y88b  d88P\n");
	printf("888       888 888       d88P   Y88b 888888888   \"Y8888P\"   \"Y8888P\"   \"Y8888P\" \n");
	printf("\n                         \"Where history comes alive\"\n\n");
	printf(MPX_VERSION_LONG);
	printf("\nType 'help' to figure things out\n");
}

/* Read, execute, print, loop */
/* RETURNS: Error code on flagrant error, OK if no probs, yo. */
int com_handler_repl(void)
{
	int done, buff_len, err, return_code,  i,j,mode;

	char input[COM_USER_INPUT_LENGTH];	
	char input_command[COM_USER_INPUT_LENGTH];
	char input_args[COM_USER_INPUT_LENGTH];
	char *s;
	char out_string[COM_USER_INPUT_LENGTH];
	
	int out_len;
	
	command_rec *requested_cmd;
	
	
	buff_len = COM_USER_INPUT_LENGTH;
	done = 0;
	return_code = 0;
	
	while (!done) {
		strcpy(out_string,"\n");
		out_len = strlen(out_string);
		sys_req(WRITE, TERMINAL, out_string, &out_len);
		
		//err = sys_req(READ, COM_PORT, input, &buff_len);
		printf("?>");
		gets(input);
		
		//printf("\n");
		
		/*strcpy(out_string,"Input Received:");
		strcat(out_string,input);
		strcat(out_string,"\n");
		out_len = strlen(out_string);*/
		//sys_req(WRITE, TERMINAL, out_string, &out_len);
		
		s = strtok(input," \t\n.,");
		strcpy(input_command, s);
		
		strcpy(input_args, "");
		s = strtok(NULL," \t\n.,");
		if (s != NULL) {
			strcpy(input_args, s);
			s = strtok(NULL," \t\n.,");
			while (s != NULL) {
				strcat(input_args," ");
				strcat(input_args, s);
				s = strtok(NULL," \t\n.,");
			}
		}
		
		if(err < 0)
			mpx_error(ERR_TERMINAL_READ_FAIL,"com_handler_repl: error code from sys_req");
		
		requested_cmd = get_command(input_command);
		
		//Execute command
		if (requested_cmd != NULL)
			return_code = requested_cmd->exec_func(input_args);
		else if (input == NULL) {
		
		}
		else {
			printf("If you're erroneously parsing and you know it, Syntax Error!\nSyntax Error (command not found)\n");
		}
		
		//sys_req(IDLE, NO_DEV, NULL, 0);
		//Parse command return codes
		if (return_code == QUIT)
			done = 1;
	}
	
	return OK;
}

/* Prints goodbye message followed by any data cleanup */
void com_handler_goodbye(void)
{
	puts("Goodbye");
}
